﻿using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Activation;

using SBPweb.PROvibe.Server.Library.Contracts;
using SBPweb.PROvibe.Server.Library.Services;

using SBPweb.PROvibe.Server.Core.Services;

using SBPweb.PROvibe.Shared.Library.Components;
using SBPweb.PROvibe.Server.Core.Modularity;
using SBPweb.PROvibe.Server.Modules.UserProvider.Contracts;

namespace SBPweb.PROvibe.Server.Core.Services
{

    [ServiceBehavior(Name = "IConfigurationProviderService", Namespace = Library.Constants.Services.CoreNamespace)]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class ConfigurationProviderService : CoreServiceBase<IConfigurationProviderService>, IConfigurationProviderService
    {

        #region Constructor logic

        public ConfigurationProviderService()
            : base()
        {
        }

        public ConfigurationProviderService(IModule parentModule)
            : base(parentModule)
        {
        }

        #endregion

        #region Properties

        public override string Name
        {
            get
            {
                return "ConfigurationProviderService";
            }
        }

        #endregion

        #region Operations
        
        [OperationBehavior(Impersonation = ImpersonationOption.Required)]
        public ICollection<Suite> EnumerateAllSuites()
        {
            if (ImpersonatedUser == null || !UserProvider.IsMemberOfRole(ImpersonatedUser, Constants.Roles.Administrator))
            {
                throw new UnauthorizedAccessException("The impersonated user is not allowed to invoke this operation!");
            }

            return new List<Suite>()
            {
                new Suite()
                {
                    Id = 1000,
                    Name = "Administrator",
                    VersionAsString = "1.0.0.0"
                },
                new Suite()
                {
                    Id = 1001,
                    Name = "Default",                    
                    VersionAsString = "1.0.0.0"
                }
            };

            throw new NotImplementedException();
        }

        [OperationBehavior(Impersonation = ImpersonationOption.Required)]
        public ICollection<Module> EnumerateAllModules()
        {
            if (ImpersonatedUser == null || !UserProvider.IsMemberOfRole(ImpersonatedUser, Constants.Roles.Administrator))
            {
                throw new UnauthorizedAccessException("The impersonated user is not allowed to invoke this operation!");
            }

            return ServerContext.Instance.ModuleManager.Modules.Cast<Module>().ToList();

            //return new List<Module>()
            //{
            //    new ServerModule()
            //    {
            //        Id = 1000,
            //        Name = "CoreModule"
            //    },
            //    new ServerModule()
            //    {
            //        Id = 1001,
            //        Name = "Module1"
            //    },
            //    new ServerModule()
            //    {
            //        Id = 1002,
            //        Name = "Module1"
            //    },
            //    new ServerModule()
            //    {
            //        Id = 1003,
            //        Name = "Module2",
            //        Version = new Version(1, 0, 0, 0)
            //    },
            //    new ClientModule()
            //    {
            //        Id = 1004,
            //        Name = "Module2",
            //        Version = new Version(1, 0, 0, 1)
            //    },
            //    new ClientModule()
            //    {
            //        Id = 1005,
            //        Name = "Module3"
            //    }
            //};

            //throw new NotImplementedException();
        }

        [OperationBehavior(Impersonation = ImpersonationOption.Required)]
        public ICollection<ServerModule> EnumerateAllServerModules()
        {
            return EnumerateAllModules().WhereTypeIs<ServerModule>().ToList();
        }

        [OperationBehavior(Impersonation = ImpersonationOption.Required)]
        public ICollection<ClientModule> EnumerateAllClientModules()
        {
            return EnumerateAllModules().WhereTypeIs<ClientModule>().ToList();
        }

        [OperationBehavior(Impersonation = ImpersonationOption.Required)]
        public ICollection<Module> EnumerateModulesOfSuite(Suite suite)
        {
            return EnumerateAllModules().Where(x => x.Id > suite.Id).ToList();
        }

        [OperationBehavior(Impersonation = ImpersonationOption.Required)]
        public ICollection<ServerModule> EnumerateServerModulesOfSuite(Suite suite)
        {
            return EnumerateAllServerModules().Where(x => x.Id > suite.Id).ToList();
        }

        [OperationBehavior(Impersonation = ImpersonationOption.Required)]
        public ICollection<ClientModule> EnumerateClientModulesOfSuite(Suite suite)
        {
            ///TODO: implement modules fetch based on suite lookup
            return EnumerateAllClientModules();
            //return EnumerateAllClientModules().Where(x => x == suite.Id).ToList();
        }

        [OperationBehavior(Impersonation = ImpersonationOption.Required)]
        public Suite GetCurrentSuite()
        {
            return EnumerateAllSuites().FirstById<Suite>(1001);
            ///TODO: implement current suite get
            ///throw new NotImplementedException();
        }

        [OperationBehavior(Impersonation = ImpersonationOption.Required)]
        public void SetCurrentSuite(Suite suite)
        {
            ///TODO: implement current suite set
            throw new NotImplementedException();
        }

        #endregion

    }

}